﻿/* 2011/11/12 */
using System;
using System.Drawing;

namespace Cosmos.Windows.Themes
{
    public class MoveCountTheme : DynamicCountTheme
    {
        public MoveCountTheme(ThemeSettings themeSettings)
            : base(themeSettings, 15, 50)
        {

        }

        protected override void PaintThemeImage(DynamicImageParameter presentParameter, DynamicImageParameter pastParameter)
        {
            PaintMoveImageByCount(presentParameter, pastParameter);
        }

        private void PaintMoveImageByCount(DynamicImageParameter presentParameter, DynamicImageParameter pastParameter)
        {
            Bitmap presentBitmap = presentParameter.Bitmap;
            string presentName = presentParameter.Name;
            string presentGroup = presentParameter.Group;
            int presentStartX = presentParameter.StartX;
            int presentStartY = presentParameter.StartY;
            int presentDisplayWidth = presentParameter.DisplayWidth;
            int presentDisplayHeight = presentParameter.DisplayHeight;
            Bitmap pastBitmap = pastParameter.Bitmap;
            string pastName = pastParameter.Name;
            string pastGroup = pastParameter.Group;
            int pastStartX = pastParameter.StartX;
            int pastStartY = pastParameter.StartY;
            int pastDisplayWidth = pastParameter.DisplayWidth;
            int pastDisplayHeight = pastParameter.DisplayHeight;

            //使用BufferedGraphics作为二次缓冲区
            Graphics bufferGraphics = _bufferedGraphics.Graphics;

            //随机选择移入图片的起始位置和移出图片的最终位置
            int presentMoveStartX = 0;
            int presentMoveStartY = 0;
            float presentMoveIntervalX = 0;
            float presentMoveIntervalY = 0;
            int pastMoveStartX = 0;
            int pastMoveStartY = 0;
            float pastMoveIntervalX = 0;
            float pastMoveIntervalY = 0;
            float imageMoveIntervalCount = (float)(_imageFrameCount);
            Random random = new Random();

            //方向表示图像位于屏幕之外时，紧贴的屏幕边缘延长线。
            int presentDirection = random.Next(4);
            switch (presentDirection)
            {
                case 0: presentMoveStartY = 0 - presentBitmap.Height;
                    presentMoveStartX = random.Next(presentBitmap.Width + _size.Width) - presentBitmap.Width; break;

                case 1: presentMoveStartY = _size.Height;
                    presentMoveStartX = random.Next(presentBitmap.Width + _size.Width) - presentBitmap.Width; break;

                case 2: presentMoveStartX = 0 - presentBitmap.Width;
                    presentMoveStartY = random.Next(presentBitmap.Height + _size.Height) - presentBitmap.Height; break;

                case 3: presentMoveStartX = _size.Width;
                    presentMoveStartY = random.Next(presentBitmap.Height + _size.Height) - presentBitmap.Height; break;

                default: break;
            }
            presentMoveIntervalX = (float)(presentStartX - presentMoveStartX) / imageMoveIntervalCount;
            presentMoveIntervalY = (float)(presentStartY - presentMoveStartY) / imageMoveIntervalCount;

            if (pastBitmap != null)
            {
                int pastDirection = random.Next(4);
                switch (pastDirection)
                {
                    case 0: pastMoveStartY = 0 - pastBitmap.Height;
                        pastMoveStartX = random.Next(pastBitmap.Width + _size.Width) - pastBitmap.Width; break;

                    case 1: pastMoveStartY = _size.Height;
                        pastMoveStartX = random.Next(pastBitmap.Width + _size.Width) - pastBitmap.Width; break;

                    case 2: pastMoveStartX = 0 - pastBitmap.Width;
                        pastMoveStartY = random.Next(pastBitmap.Height + _size.Height) - pastBitmap.Height; break;

                    case 3: pastMoveStartX = _size.Width;
                        pastMoveStartY = random.Next(pastBitmap.Height + _size.Height) - pastBitmap.Height; break;

                    default: break;
                }
                pastMoveIntervalX = (float)(pastStartX - pastMoveStartX) / imageMoveIntervalCount;
                pastMoveIntervalY = (float)(pastStartY - pastMoveStartY) / imageMoveIntervalCount;
            }

            float presentDrawX = presentMoveStartX;
            float presentDrawY = presentMoveStartY;
            float pastDrawX = pastStartX;
            float pastDrawY = pastStartY;
            CheckThreadBeforePainting();
            for (int i = 0; i < _imageFrameCount; i++)
            {
                if (_cancellationRequested)
                    break;

                bufferGraphics.Clear(_backColor);

                if (pastBitmap != null)
                {
                    pastDrawX -= pastMoveIntervalX;
                    pastDrawY -= pastMoveIntervalY;
                    bufferGraphics.DrawImageUnscaled(pastBitmap, (int)Math.Round(pastDrawX), (int)Math.Round(pastDrawY), pastDisplayWidth, pastDisplayHeight);
                }

                presentDrawX += presentMoveIntervalX;
                presentDrawY += presentMoveIntervalY;
                bufferGraphics.DrawImageUnscaled(presentBitmap, (int)Math.Round(presentDrawX), (int)Math.Round(presentDrawY), presentDisplayWidth, presentDisplayHeight);

                DrawFileInformation(bufferGraphics, presentName, presentGroup);

                SuspendThreadAfterPainted();
                _bufferedGraphics.Render(Graphics.FromHwnd(_formHandle));
            }
        }

        /// <summary>
        /// 初始化时将动态过程中每帧的屏幕结果在数组中，动态绘制时直接绘制数组中的结果。
        /// </summary>
        private void PaintMoveImageByInitialization(DynamicImageParameter presentParameter, DynamicImageParameter pastParameter)
        {
            Bitmap presentBitmap = presentParameter.Bitmap;
            string presentName = presentParameter.Name;
            string presentGroup = presentParameter.Group;
            int presentStartX = presentParameter.StartX;
            int presentStartY = presentParameter.StartY;
            int presentDisplayWidth = presentParameter.DisplayWidth;
            int presentDisplayHeight = presentParameter.DisplayHeight;
            Bitmap pastBitmap = pastParameter.Bitmap;
            string pastName = pastParameter.Name;
            string pastGroup = pastParameter.Group;
            int pastStartX = pastParameter.StartX;
            int pastStartY = pastParameter.StartY;
            int pastDisplayWidth = pastParameter.DisplayWidth;
            int pastDisplayHeight = pastParameter.DisplayHeight;

            //使用BufferedGraphics作为二次缓冲区
            Graphics bufferGraphics = _bufferedGraphics.Graphics;

            //随机选择移入图片的起始位置和移出图片的最终位置
            int theMoveStartX = 0;
            int theMoveStartY = 0;
            float theMoveIntervalX = 0;
            float theMoveIntervalY = 0;
            int pastMoveStartX = 0;
            int pastMoveStartY = 0;
            float pastMoveIntervalX = 0;
            float pastMoveIntervalY = 0;
            float imageMoveIntervalCount = (float)(_imageFrameCount);
            Random random = new Random();
            int theDirection = random.Next(4);
            switch (theDirection)
            {
                case 0: theMoveStartY = 0 - presentBitmap.Height;
                    theMoveStartX = random.Next(presentBitmap.Width + _size.Width) - presentBitmap.Width; break;

                case 1: theMoveStartY = _size.Height;
                    theMoveStartX = random.Next(presentBitmap.Width + _size.Width) - presentBitmap.Width; break;

                case 2: theMoveStartX = 0 - presentBitmap.Width;
                    theMoveStartY = random.Next(presentBitmap.Height + _size.Height) - presentBitmap.Height; break;

                case 3: theMoveStartX = _size.Width;
                    theMoveStartY = random.Next(presentBitmap.Height + _size.Height) - presentBitmap.Height; break;

                default: break;
            }
            theMoveIntervalX = (float)(presentStartX - theMoveStartX) / imageMoveIntervalCount;
            theMoveIntervalY = (float)(presentStartY - theMoveStartY) / imageMoveIntervalCount;

            if (pastBitmap != null)
            {
                int pastDirection = random.Next(4);
                switch (pastDirection)
                {
                    case 0: pastMoveStartY = 0 - pastBitmap.Height;
                        pastMoveStartX = random.Next(pastBitmap.Width + _size.Width) - pastBitmap.Width; break;

                    case 1: pastMoveStartY = _size.Height;
                        pastMoveStartX = random.Next(pastBitmap.Width + _size.Width) - pastBitmap.Width; break;

                    case 2: pastMoveStartX = 0 - pastBitmap.Width;
                        pastMoveStartY = random.Next(pastBitmap.Height + _size.Height) - pastBitmap.Height; break;

                    case 3: pastMoveStartX = _size.Width;
                        pastMoveStartY = random.Next(pastBitmap.Height + _size.Height) - pastBitmap.Height; break;

                    default: break;
                }
                pastMoveIntervalX = (float)(pastStartX - pastMoveStartX) / imageMoveIntervalCount;
                pastMoveIntervalY = (float)(pastStartY - pastMoveStartY) / imageMoveIntervalCount;
            }

            float presentDrawX = theMoveStartX;
            float presentDrawY = theMoveStartY;
            float pastDrawX = pastStartX;
            float pastDrawY = pastStartY;
            Bitmap[] bufferBitmaps = new Bitmap[_imageFrameCount];
            for (int i = 0; i < _imageFrameCount; i++)
            {
                bufferBitmaps[i] = new Bitmap(_size.Width, _size.Height);
                Graphics bitmapGraphics = Graphics.FromImage(bufferBitmaps[i]);

                bitmapGraphics.Clear(_backColor);

                if (pastBitmap != null)
                {
                    pastDrawX -= pastMoveIntervalX;
                    pastDrawY -= pastMoveIntervalY;
                    bitmapGraphics.DrawImage(pastBitmap, pastDrawX, pastDrawY, pastDisplayWidth, pastDisplayHeight);
                }

                presentDrawX += theMoveIntervalX;
                presentDrawY += theMoveIntervalY;
                bitmapGraphics.DrawImage(presentBitmap, presentDrawX, presentDrawY, presentDisplayWidth, presentDisplayHeight);

                DrawFileInformation(bufferGraphics, presentName, presentGroup);
            }

            CheckThreadBeforePainting();
            for (int i = 0; i < _imageFrameCount; i++)
            {
                bufferGraphics.Clear(_backColor);
                bufferGraphics.DrawImageUnscaled(bufferBitmaps[i], 0, 0);
                bufferBitmaps[i].Dispose();
                SuspendThreadAfterPainted();
                _bufferedGraphics.Render(Graphics.FromHwnd(_formHandle));
            }
        }
    }
}
